﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Media3D;
using CommunityToolkit.Mvvm.Messaging;
using machine_registration.Helpers;
using machine_registration.Models;
using machine_registration.ViewModels;
using machine_registration.Views.Pages;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Wpf.Ui;

namespace machine_registration.ViewModels
{
    /// <summary>
    /// 设备借出管理
    /// </summary>
    public partial class BorrowPageViewModel : ViewModel
    {
  
        [ObservableProperty]   
        private BorrowRecord record = new();

        private readonly AppDbContext _db;
        /// <summary>
        /// 设备类型选项
        /// </summary>
        public List<DeviceTypeOption> DeviceTypes { get; } = Enum.GetValues(typeof(DeviceType))
            .Cast<DeviceType>()
            .Select(t => new DeviceTypeOption(t))
            .ToList();
        private INavigationService? navigationService;
        public BorrowPageViewModel(AppDbContext dbContext, INavigationService navigationService)
        {
            _db = dbContext;
            _db.Database.EnsureCreated(); // 自动创建数据库 
           this. navigationService = navigationService;

    
         WeakReferenceMessenger.Default.Register<PageNavigationMessage, string>(
         recipient: this,                  // 消息接收者
         token: "BorrowPageToken",             // 指定消息令牌
         handler: (r, m) =>                // 消息处理程序
         {
             OnNavigationMessageReceived(m.Value);
         });

        }
       
        private void OnNavigationMessageReceived(DeviceInventory value)
        {
            Record.DeviceName = value.DeviceName;
            Record.DeviceType = value.DeviceType;
            Record.Isfactory = value.IsRetired;
            Record.MachineId = value.MachineId;
            Record.SerialNumber = value.SerialNumber;
            Record.Status = InventoryStatus.Pending;
            Record.OwnerId= value.OwnerId;

        }

        [RelayCommand]
        private void Reset()
        {
     
           Record = new BorrowRecord();

        }

        [RelayCommand]
        private async Task Submit()
        {
      
            var validation = Record.ValidateProperties();
            if (!validation.isok)
            {
                await ShowDialog("验证失败", validation.erro);
                return;
            }

            try
            {
                // 通过 MachineId 获取设备库存记录
                var device = await _db.DeviceInventorys
                    //.AsNoTracking()// 不跟踪数据库
                    .Include(d => d.BorrowRecords)
                    .FirstOrDefaultAsync(d => d.MachineId == Record.MachineId);

                if (device == null)
                {
                    await ShowDialog("错误", "未找到对应设备");
                    return;
                }

                // 检查设备状态是否可借出
                if (device.Status != InventoryStatus.InStock)
                {
                    await ShowDialog("错误", $"设备当前状态不可借出，状态：{device.Status?.GetDescription()}");
                    return;
                }

                // 使用事务保证数据一致性
                using var transaction = await _db.Database.BeginTransactionAsync();

                try
                {
                    // 重新附加实体到上下文 (因之前用了 AsNoTracking)
                    _db.Attach(device);
                    // 关联设备与借出记录
                    device.BorrowRecords.Add(new BorrowRecord
                    {
                        //InventoryId = 0,//添加主键 强制设为未跟踪状态
                        // 从界面绑定复制数据
                        DeviceName = Record.DeviceName,
                        BorrowDate = Record.BorrowDate ,
                        ExpectedReturnDate = Record.ExpectedReturnDate,
                        Isfactory = Record.Isfactory,
                        OwnerId=Record.OwnerId,
                        Status=Record.Status,
                        Counterpart=Record.Counterpart,
                        // 自动记录设备信息
                        DeviceType = device.DeviceType,
                        MachineId = device.MachineId,
                        SerialNumber = device.SerialNumber
                    });

                    // 更新设备状态
                    device.Status = InventoryStatus.Pending;
                    device.CurrentKeeper = Record.Counterpart;

                    // 保存更改
                    await _db.SaveChangesAsync();
                    await transaction.CommitAsync();
                    //  刷新实体状态
                    await _db.Entry(device).ReloadAsync();
                    await ShowDialog("成功", $"设备 {device.MachineId} 借出登记成功");
                    Reset();
                    _ = navigationService.GoBack();
                    // 清理新实体的跟踪状态
                    _db.Entry(device).State = EntityState.Detached;
                }
                catch
                {
                    await transaction.RollbackAsync();
                    throw;
                }
            }
            catch (DbUpdateException ex)
            {
                await HandleDatabaseError(ex);
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"操作失败: {ex.Message}");
                await ShowDialog("错误", $"操作失败: {ex.Message}");
            }
        }
        private async Task ShowDialog(string title, string content)
        {
            var dialog = new Wpf.Ui.Controls.MessageBox
            {
                Title = title,
                Content = content,
                CloseButtonText = "我已知晓"
            };
            await dialog.ShowDialogAsync();
        }

        private async Task HandleDatabaseError(DbUpdateException ex)
        {
            var errorMessage = ex.InnerException switch
            {
                SqliteException sqlEx when sqlEx.SqliteErrorCode == 19
                    => "唯一性约束冲突，请检查数据重复",
                _ => $"数据库操作失败：{ex.Message}"
            };

            await ShowDialog("系统错误", errorMessage);
        }
    }

    // 设备类型选项模型
    public class DeviceTypeOption
    {
        public DeviceType Value { get; }
        public string Description { get; }

        public DeviceTypeOption(DeviceType type)
        {
            Value = type;
            Description = type.GetDescription();
        }
    }
  
  
}

